package com.example.exam.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.commonutils.JwtUtils;
import com.example.commonutils.ResultData;
import com.example.exam.dto.ExamTopicStuDTO;
import com.example.exam.dto.ExamTopicTchDTO;
import com.example.exam.dto.TopicTchDTO;
import com.example.exam.entity.Exam;
import com.example.exam.entity.ExamTopic;
import com.example.exam.entity.QueryCondition;
import com.example.exam.entity.Topic;
import com.example.exam.mapper.ExamMapper;
import com.example.exam.service.ExamService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.exam.service.ExamTopicService;
import com.example.exam.service.TopicService;
import org.springframework.beans.BeanUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 江晨晖
 * @since 2022-12-15
 */
@Service
public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements ExamService {

    @Autowired
    private TopicService topicService;

    @Autowired
    private ExamTopicService examTopicService;

    @Override
    public ResultData insert(ExamTopicTchDTO examTopicTchDTO, int userId) {
        try {
            Exam exam = new Exam();
            BeanUtils.copyProperties(examTopicTchDTO, exam);
            exam.setCreatorId(userId);
            exam.setCreateDate(new Date());
            exam.setUpdateDate(new Date());
            save(exam);

//            List<TopicTchDTO> topicTchDTOList = examTopicTchDTO.getTopicTchDTOList();
//            List<Topic> collect = topicTchDTOList.stream().map(topic -> {
//                Topic t = new Topic();
//                BeanUtils.copyProperties(topic, t);
//                t.setCreatorId(userId);
//                t.setCreateDate(new Date());
//                t.setUpdateDate(new Date());
//                t.setSubjectId(exam.getSubjectId());
//                t.setSubjectName(exam.getSubjectName());
//                return t;
//            }).collect(Collectors.toList());
//
//            topicService.saveBatch(collect);
//
//            List<ExamTopic> examTopics = topicTchDTOList.stream().map(topic -> {
//                ExamTopic examTopic = new ExamTopic(null, exam.getExamId(), topic.getTopicId(), topic.getTopicType());
//                return examTopic;
//            }).collect(Collectors.toList());
//            System.err.println(examTopics);
//            examTopicService.saveBatch(examTopics);

            Topic t = new Topic();
            for (TopicTchDTO topic : examTopicTchDTO.getTopicTchDTOList()) {
                BeanUtils.copyProperties(topic, t);

                t.setCreatorId(userId);
                t.setCreateDate(new Date());
                t.setUpdateDate(new Date());
                t.setSubjectId(exam.getSubjectId());
                t.setSubjectName(exam.getSubjectName());

                topicService.save(t);
                examTopicService.save(new ExamTopic(null, exam.getExamId(), t.getTopicId(), t.getTopicType()));
            }

            return ResultData.ok();
        } catch (Exception e) {
            //强制手动事务回滚
            e.printStackTrace();
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultData.error().message(e.getMessage());
        }
    }

    @Override
    public ResultData selectByPrimaryKey(int examId) {
        ExamTopicTchDTO examTopicTchDTO = baseMapper.selectByPrimaryKey(examId);
        if (examTopicTchDTO == null) {
            return ResultData.error().message("请求失败");
        }
        return ResultData.ok().data("testData", examTopicTchDTO);
    }

    @Override
    @Transactional
    public ResultData deleteTestPaperById(Integer id) {
        //删除试卷
        LambdaQueryWrapper<Exam> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Exam::getExamId, id);
        remove(wrapper);
        //查询试卷与题目的关联关系
        LambdaQueryWrapper<ExamTopic> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ExamTopic::getExamId, id);
        List<ExamTopic> list = examTopicService.list(queryWrapper);
        List<Integer> collect = list.stream().map(examTopic -> examTopic.getTopicId()).collect(Collectors.toList());
        examTopicService.remove(queryWrapper);
        topicService.removeByIds(collect);
        return ResultData.ok();
    }

    @Override
    @Transactional
    public ResultData updateByPrimaryKeySelective(ExamTopicTchDTO examTopicTchDTO) {
        Exam exam = new Exam();
        BeanUtils.copyProperties(examTopicTchDTO, exam);
        baseMapper.updateById(exam);
        List<ExamTopic> list = examTopicService.list(new LambdaQueryWrapper<ExamTopic>().eq(ExamTopic::getExamId, examTopicTchDTO.getExamId()));
        List<Integer> oldTopicIdList = list.stream().map(examTopic -> {
            return examTopic.getTopicId();
        }).collect(Collectors.toList());
        System.out.println(oldTopicIdList);
        //判断更新后的题目是否存在  存在则更新   不存在则添加  剩下没有匹配到的则删除记录
        for (TopicTchDTO t : examTopicTchDTO.getTopicTchDTOList()) {

            Topic topic = new Topic();
            BeanUtils.copyProperties(t, topic);
            System.err.println(t.getTopicId());
            boolean isHas = false;
            for (int i = 0; i < oldTopicIdList.size(); i++) {
                if (t.getTopicId() == oldTopicIdList.get(i)) {
                    isHas = true;
                    //存在则更新
                    topicService.updateById(topic);
                    //移出旧的试卷id集合
                    oldTopicIdList.remove(i);
                    break;
                }
            }
            //不存在则添加
            if (isHas == false) {
                topic.setTopicId(null);
                topic.setCreatorId(examTopicTchDTO.getCreatorId());
                topic.setSubjectId(examTopicTchDTO.getSubjectId());
                topic.setSubjectName(examTopicTchDTO.getSubjectName());
                topic.setUpdateDate(new Date());
                topic.setCreateDate(new Date());
                topicService.save(topic);
                examTopicService.save(new ExamTopic(null, examTopicTchDTO.getExamId(), topic.getTopicId(), topic.getTopicType()));
            }
        }
        //剩下没有匹配到的则删除
        topicService.removeByIds(oldTopicIdList);
        for (Integer oldT_id : oldTopicIdList) {
            examTopicService.remove(new LambdaQueryWrapper<ExamTopic>().eq(ExamTopic::getExamId, examTopicTchDTO.getExamId())
                    .eq(ExamTopic::getTopicId, oldT_id));
        }

        return ResultData.ok();
    }

    @Override
    public ResultData stuSelectByPrimaryKey(int examId, HttpServletRequest request) {
        String token = request.getHeader("token");
        if (StringUtils.hasText(token)) {
            String userId = JwtUtils.getMemberIdByJwtToken(request);
            ExamTopicStuDTO examTopicStuDTO = baseMapper.stuSelectByPrimaryKey(examId,userId);
            if (examTopicStuDTO == null) {
                return ResultData.error().message("请求失败");
            }
            //学生未完成试卷
            if (examTopicStuDTO.getUserGrade().getExamStatus() == null) {
                examTopicStuDTO.setUserGrade(null);
                examTopicStuDTO.setUserTopicList(null);
            }
            return ResultData.ok().data("testData", examTopicStuDTO);
        }
        return ResultData.error().message("请登录");
    }

    @Override
    public ResultData getTestPaper(QueryCondition queryCondition, HttpServletRequest request) {
        LambdaQueryWrapper<Exam> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.hasText(queryCondition.getCourseId()),Exam::getCourseId,queryCondition.getCourseId());
        if(StringUtils.hasText(queryCondition.getKeyword())){
            wrapper.eq(Exam::getExamId,queryCondition.getKeyword()).or().like(Exam::getExamName,queryCondition.getKeyword());
        }
        Page page = new Page(queryCondition.getCurrentPage(),queryCondition.getPageSize());
        page(page,wrapper);
        return ResultData.ok().data("content",page.getRecords()).data("total",page.getTotal());
    }
}
